package com.czj.service.impl;

import com.czj.common.api.CommonResult;
import com.czj.common.service.RedisService;
import com.czj.dao.UserRoleRelationDao;
import com.czj.dto.CardParam;
import com.czj.mapper.CardMapper;
import com.czj.mapper.UserMapper;
import com.czj.model.*;
import com.czj.security.utils.JwtTokenUtil;
import com.czj.service.UserService;
import com.czj.utils.AliSmsUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class UserServiceImpl implements UserService {

    private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserRoleRelationDao userRoleRelationDao;
    @Autowired
    private CardMapper cardMapper;
    @Autowired
    private RedisService redisService;

    @Override
    public User getUserByUsername(String username) {
        UserExample example = new UserExample();
        example.createCriteria().andUsernameEqualTo(username);
        List<User> userList = userMapper.selectByExample(example);
        if (userList != null && userList.size() > 0) {
            return userList.get(0);
        }
        return null;
    }

    @Override
    public User register(User user) {
        //查询是否有相同用户名的用户
        UserExample example = new UserExample();
        example.createCriteria().andUsernameEqualTo(user.getUsername()).andPhoneEqualTo(user.getPhone());
        List<User> userList = userMapper.selectByExample(example);
        if (userList.size() > 0) {
            return null;
        }
        //将密码进行加密操作
        String encodePassword = passwordEncoder.encode(user.getPassword());
        user.setPassword(encodePassword);
        userMapper.insertSelective(user);
        return user;
    }

    @Override
    public String login(String username, String password) {
        String token = null;
        try {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (!passwordEncoder.matches(password, userDetails.getPassword())) {
                throw new BadCredentialsException("密码不正确");
            }
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);


            token = jwtTokenUtil.generateToken(userDetails);
        } catch (AuthenticationException e) {
            LOGGER.warn("登录异常:{}", e.getMessage());
        }
        return token;
    }

    @Override
    public List<Permission> getPermissionList(Integer userId) {
        return userRoleRelationDao.getPermissionList(userId);
    }

    @Override
    public CommonResult<String> insertCard(String username, CardParam cardParam) {
        if (StringUtils.isEmpty(cardParam)){
            return CommonResult.failed("请输入信息");
        }

        Card card = new Card();
        BeanUtils.copyProperties(cardParam,card);

        UserExample userExample = new UserExample();
        userExample.createCriteria().andUsernameEqualTo(username);
        List<User> userList = userMapper.selectByExample(userExample);
        User user = userList.get(0);

        CardExample cardExample = new CardExample();
        CardExample.Criteria criteria1 = cardExample.createCriteria();
        criteria1.andUserIdEqualTo(user.getId());

        CardExample.Criteria criteria2 = cardExample.createCriteria();
        criteria2.andCardEqualTo(card.getCard());
        cardExample.or(criteria2);

        List<Card> cardList = cardMapper.selectByExample(cardExample);
        if (cardList.size() == 1){
            user.setAuthentication("1");
            userMapper.updateByPrimaryKeySelective(user);
            return CommonResult.failed("该用户已认证");
        }

        card.setUserId(user.getId());
        int result = cardMapper.insertSelective(card);
        if (result == 1){
            user.setAuthentication("1");
            userMapper.updateByPrimaryKeySelective(user);

            return CommonResult.success("添加认证成功！");
        }else {
            return CommonResult.failed("添加认证失败！");
        }
    }

    @Override
    public CommonResult<String> updateUserById(User user) {
        if (StringUtils.isEmpty(user)){
            return CommonResult.failed("请输入信息！");
        }
        int result = userMapper.updateByPrimaryKeySelective(user);
        if (result == 1){
            return CommonResult.success("修改成功！");
        }else {
            return CommonResult.failed("修改失败！");
        }
    }

    @Override
    public CommonResult<String> deleteUserById(String username) {
        //查询是否有相同用户名的用户
        UserExample example = new UserExample();
        example.createCriteria().andUsernameEqualTo(username);
        List<User> userList = userMapper.selectByExample(example);
        if (userList.size() == 1) {
            int result = userMapper.deleteByPrimaryKey(userList.get(0).getId());
            if (result == 1){
                return CommonResult.success("注销成功！");
            } else {
                return CommonResult.failed("注销失败！");
            }
        } else {
            return CommonResult.failed("该用户不存在！");
        }
    }

    @Override
    public CommonResult getCode(String username) {
        //查询是否有相同用户名的用户
        UserExample example = new UserExample();
        example.createCriteria().andUsernameEqualTo(username);
        List<User> userList = userMapper.selectByExample(example);
        if (userList.size() == 1) {
            String phone = userList.get(0).getPhone();

            //此处返回验证码，当作发送验证码了
            int code = AliSmsUtil.randomNum(6);
            redisService.set(phone,code + "",60);

            HashMap<Object, Object> codeMap = new HashMap<>();
            codeMap.put(phone,code);
            //发送验证码
            AliSmsUtil.sendSmsCode(phone,code+"",AliSmsUtil.SMS_TEM_LOGIN);

            return CommonResult.success(codeMap,"发送验证码成功,请注意查收！");
        } else {
            return CommonResult.failed("发送失败！");
        }
    }

    @Override
    public CommonResult checkCode(String username,String code) {
        if (StringUtils.isEmpty(code)){
            return CommonResult.failed("请输入验证码!");
        }
        UserExample example = new UserExample();
        example.createCriteria().andUsernameEqualTo(username);
        List<User> userList = userMapper.selectByExample(example);

        if (redisService.get(userList.get(0).getPhone()) != null && redisService.get(userList.get(0).getPhone()).equals(code)){
            redisService.del(userList.get(0).getPhone());
            return CommonResult.success("验证码正确！");
        }else {
            return CommonResult.failed("验证码错误！");
        }
    }
}
